#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <cstring>
#include <cstdio>

class Task
{
public:
    Task(int a, int b)
        :_a(a)
        ,_b(b)
    {}

    int Execute()
    {
        return _a + _b;
    }


    ~Task()
    {}
private:
    int _a;
    int _b;
};

class Result
{
public:

    Result(int res)
        :_res(res)
    {}

    int GetResult()
    {
        return _res;
    }
private:
    int _res;
};

//pthread_exit
void* runTest01(void* args)
{
    Task* t = static_cast<Task*>(args);
    std::cout << "计算中..." << std::endl;
    Result* res = new Result(t->Execute());
    sleep(2);
    std::cout << "计算结果为: " << res->GetResult() << std::endl;

    pthread_exit(res);
}

void test01()
{
    pthread_t pid;
    Task* t = new Task(1, 2);

    int n = pthread_create(&pid, nullptr, runTest01, (void*)t);

    Result* ret = nullptr;
    pthread_join(pid, (void**)&ret);
    std::cout << "pthread_exit携带的退出信息为: " << ret->GetResult() << std::endl;
}

//pthread_cancel
void* runTest02(void* args)
{
    Task* t = static_cast<Task*>(args);
    std::cout << "计算中..." << std::endl;
    Result* res = new Result(t->Execute());
    sleep(2);
    std::cout << "计算结果为: " << res->GetResult() << std::endl;
    sleep(2);
    return res;
}

void test02()
{
    pthread_t pid;
    Task* t = new Task(1, 2);

    pthread_create(&pid, nullptr, runTest02, (void*)t);

    
    sleep(3);
    pthread_cancel(pid);
    std::cout << "已取消线程" << std::endl;
    
    Result* ret = nullptr;
    int n = pthread_join(pid, (void**)&ret);
    if(n != 0)
    {
        std::cout << "jion失败，退出码: " << n << std::endl;
    }
    else
        //std::cout << "pthread_exit退出成功，ret: " << ret->GetResult() << std::endl;
        std::cout << "pthread_exit退出成功" << std::endl;
}


//pthread_detach
void* runTest03(void* args)
{
    Task* t = static_cast<Task*>(args);
    std::cout << "计算中..." << std::endl;
    Result* res = new Result(t->Execute());
    sleep(2);
    std::cout << "计算结果为: " << res->GetResult() << std::endl;

    return res;
}

void test03()
{
    pthread_t pid;
    Task* t = new Task(1, 2);



    pthread_create(&pid, nullptr, runTest01, (void*)t);

    pthread_detach(pid);
    std::cout << "线程已经分离" << std::endl;

    std::cout << "main:等待线程结束中..." << std::endl;
    sleep(5);

    Result* ret = nullptr;
    int n = pthread_join(pid, (void**)&ret);
    if(n != 0)
    {
        std::cout << "线程join失败，错误码:" << n << " 错误原因: " << strerror(n) << std::endl;
    }
    else
        std::cout << "pthread_exit携带的退出信息为: " << ret->GetResult() << std::endl;
}


int main()
{
    //test01();
    //test02();
    //test03();
    return 0;
}